/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.eng.scc.core.conn.serial;

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.TooManyListenersException;

/**
 *
 * @author Rafael
 */
public class SerialPoolManager
{
    private RXTX txrx = new RXTX();
    
    private static SerialPoolManager manager = null;
    
    private SerialPort serialPort = null;
    private InputStream is = null;
    private OutputStream out = null;
    
    private boolean isClosed = false;
    
    private void init( String port )
    {
        try
        {
            ( new SerialPoolManager() ).connect( port );
        }
        catch ( PortInUseException e )
        {
            System.err.println( "Porta em uso!" );
            isClosed = true;
        }
        catch ( NoSuchPortException e )
        {
//            contact.writeLog( id, "the connection could not be made" );
            e.printStackTrace();
            isClosed = true;
        }
        catch ( UnsupportedCommOperationException e )
        {
//            contact.writeLog( id, "the connection could not be made" );
            e.printStackTrace();
            isClosed = true;
        }
        catch ( IOException e )
        {
//            contact.writeLog( id, "the connection could not be made" );
            e.printStackTrace();
            isClosed = true;
        }
        catch ( TooManyListenersException ex )
        {
            ex.printStackTrace();
            isClosed = true;
        }
    }

    private SerialPoolManager()
    {
    }

    public static SerialPoolManager getInstance( String port )
    {
        if ( manager == null )
        {
            manager = new SerialPoolManager();
        }
        
        if ( ! manager.isClosed )
        {
            manager.init( port );
        }
        
        return manager;
    }
    
    public void connect( String portName ) throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException, IOException, TooManyListenersException
    {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier( portName );
        
//        portIdentifier.addPortOwnershipListener( new CommPortOwnershipListener()
//        {
//            protected boolean owned = false;
//            
//            @Override
//            public void ownershipChange( int i )
//            {
//                switch ( i )
//                {
//                    case PORT_OWNED:
//                        System.out.println( "An open succeeded." );
//                        owned = true;
//                        break;
//                    case PORT_UNOWNED:
//                        System.out.println( "A close succeeded." );
//                        owned = false;
//                        break;
//                    case PORT_OWNERSHIP_REQUESTED:
//                        if ( owned )
//                        {
//                            if ( JOptionPane.showConfirmDialog( null,
//                                                                "I've been asked to give up the port, should I?",
//                                                                "Port Conflict ()",
//                                                                JOptionPane.OK_CANCEL_OPTION ) == 0 )
//                            {
//                                serialPort.close();
//                            }
//                        }
//                        else
//                        {
//                            System.out.println( "Somebody else has the port" );
//                        }
//                }
//            }
//        });
        
        System.err.println( "Connection to: " + portName );
        
        if ( portIdentifier.isCurrentlyOwned() )
        {
            System.err.println( "Port already in use" );
        }
        else
        {
            CommPort commPort = portIdentifier.open( this.getClass().getName(), 2000 );

            if ( commPort instanceof SerialPort )
            {
                serialPort = ( SerialPort ) commPort;
                
                serialPort.setSerialPortParams( 115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE );

                 is = serialPort.getInputStream();

                 out = serialPort.getOutputStream();
//
//                ( new Thread( new SerialWriter( out ) ) ).start();

                 serialPort.addEventListener( txrx.new SerialReader( is, out ) );
//                serialPort.addEventListener( txrx.new SerialWriter( out ) );
                serialPort.notifyOnDataAvailable( true );
            }
            
            else
            {
                System.err.println( "Error: Only serial ports are handled." );
            }
        }
    }
    
    public static void main( String[] args )
    {
        SerialPoolManager.getInstance( "COM4" );
    }
    
    public synchronized void disconnect()
    {
        try
        {
            is.close();
        }
        catch ( IOException ex )
        {
            ex.printStackTrace();
        }
        
        if ( serialPort != null )
        {
            serialPort.removeEventListener();
            serialPort.close();
        }
        
        isClosed = true;
    }
}
